﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Media;
using System.Windows.Forms;
using Client.Properties;
using LuatChoi;
using Utility;
using Timer = System.Threading.Timer;
using System.Threading;

namespace Client
{
    public partial class frmGame : Form
    {
        private readonly ThongTinNguoiChoi QuanDich;
        private readonly ThongTinNguoiChoi QuanTa;
        private readonly int ThoiGianLuotDi = 600;


        private bool DangChoi;
        public bool DuocPhepDiChuyen;
        private int SoLanDiChuyen;
        private int ThoiGianQuanDich;
        private int ThoiGianQuanMinh;
        public List<Vector> ToaDoBiChieu;
        public Vector ToaDoDangChon;
        public List<Vector> ToaDoDiChuyen;
        public List<Vector> ToaDoTanCong;
        public Vector ToaDoVuaDiDen;
        public Vector ToaDoVuaRoiKhoi;
        private int TongThoiGian;
        private BanCo banCo;
        private Graphics gimg, gpn;
        private Image img;
        private Timer t;

        public frmGame()
        {
            InitializeComponent();
        }

        public frmGame(string tenDoiThu, Phe quanMinh)
            : this()
        {
            QuanTa = new ThongTinNguoiChoi
                {
                    Mau = quanMinh,
                    Ten = frmClient.client.UserName,
                    QuanDaAn = new List<QuanCo>(),
                    SoTranThang = 0,
                };
            QuanDich = new ThongTinNguoiChoi
                {
                    Mau = quanMinh == Phe.Trang ? Phe.Den : Phe.Trang,
                    Ten = tenDoiThu,
                    QuanDaAn = new List<QuanCo>(),
                    SoTranThang = 0,
                };
            CapNhatThongTinVanChoi();
        }

        public event EventHandler ThayDoiHienThiDanhSach;
        public event EventHandler BoCuoc;
        public event EventHandler BatDauGame;
        public event EventHandler Thoat;
        public event EventHandler<ChatArgs> TroChuyen;
        public event EventHandler<DiChuyenArgs> DiChuyen;
        public event EventHandler<PhongTotArg> PhongTot;


        private void CapNhatThongTinVanChoi()
        {
            banCo = new BanCo();
            Text = string.Format("Cờ vua - {0} vs {1}", QuanTa.Ten, QuanDich.Ten);
            lbTenBan.Text = QuanDich.Ten;
            lbTenMinh.Text = QuanTa.Ten;
            lbMauBan.Text = QuanDich.Mau == Phe.Den ? "Đen" : "Trắng";
            lbMauMinh.Text = QuanTa.Mau == Phe.Den ? "Đen" : "Trắng";
            lbThangMinh.Text = QuanTa.SoTranThang.ToString();
            lbThangBan.Text = QuanDich.SoTranThang.ToString();
            DuocPhepDiChuyen = QuanTa.Mau == Phe.Trang;
            SoLanDiChuyen = 0;
            DangChoi = false;
            TongThoiGian = ThoiGianQuanMinh = ThoiGianQuanDich = 0;
            btnBatDau.Enabled = true;
            btnBoCuoc.Enabled = false;
            ToaDoDiChuyen = new List<Vector>();
            ToaDoTanCong = new List<Vector>();
            ToaDoBiChieu = new List<Vector>();
            lvNhatKy.Items.Clear();
            try
            {
                t.Dispose();
            }
            catch
            {
            }
        }

        private void frmGame_Load(object sender, EventArgs e)
        {
            CheckForIllegalCrossThreadCalls = false;
            SetStyle(
                ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
            gpn = pnHinh.CreateGraphics();
            img = new Bitmap(pnHinh.Width, pnHinh.Height);
            gimg = Graphics.FromImage(img);
        }

        private void cbHienThiDanhSach_CheckedChanged(object sender, EventArgs e)
        {
            if (ThayDoiHienThiDanhSach != null)
            {
                ThayDoiHienThiDanhSach(cbHienThiDanhSach.Checked, EventArgs.Empty);
            }
        }

        private void btnChat_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(txtChatText.Text))
            {
                if (TroChuyen != null)
                {
                    var arg = new ChatArgs(txtChatText.Text, QuanDich.Ten);
                    TroChuyen(this, arg);
                }
                LuuNhatKyChat(frmClient.client.UserName, txtChatText.Text);
                txtChatText.Clear();
            }
        }



        private void btnBatDau_Click(object sender, EventArgs e)
        {
            if (BatDauGame != null)
            {
                BatDauGame(this, EventArgs.Empty);
                btnBatDau.Enabled = false;
            }
        }


        public void BatDauChoi()
        {
            btnBoCuoc.Enabled = true;
            DangChoi = true;
            VeBanCo();
            TongThoiGian = 0;
            ResetThoiGian();

            t = new Timer(state =>
                {
                    lbTongThoiGian.Text = TinhToan.TinhThoiGian(TongThoiGian++);
                    if (DuocPhepDiChuyen)
                        lbThoiGianMinh.Text = TinhToan.TinhThoiGian(ThoiGianQuanMinh--);
                    else
                        lbThoiGianBan.Text = TinhToan.TinhThoiGian(ThoiGianQuanDich--);
                }, null, 1000, 1000);
            lbStatus.Text = "Trận đấu đã bắt đầu!";
        }

        private void VeBanCo()
        {
            gimg.DrawImage(Resources.bg_den, new Rectangle(0, 0, 425, 425));

            ToaDoDiChuyen.ForEach(t =>
                {
                    Rectangle rect = TinhToan.ChuyenThanhToaDoHinh(t.X, t.Y, QuanTa.Mau);
                    gimg.FillRectangle(ButVe.BDiChuyen, rect);
                    gimg.DrawRectangle(ButVe.PDiChuyen, rect);
                });

            ToaDoTanCong.ForEach(t =>
                {
                    Rectangle rect = TinhToan.ChuyenThanhToaDoHinh(t.X, t.Y, QuanTa.Mau);
                    gimg.FillRectangle(ButVe.BTanCong, rect);
                    gimg.DrawRectangle(ButVe.PTanCong, rect);
                });

            if (ToaDoDangChon != null)
            {
                Rectangle rect = TinhToan.ChuyenThanhToaDoHinh(ToaDoDangChon.X, ToaDoDangChon.Y,
                                                               QuanTa.Mau);
                gimg.FillRectangle(ButVe.BDangChon, rect);
                gimg.DrawRectangle(ButVe.PDangChon, rect);
            }

            if (ToaDoVuaDiDen != null)
            {
                Rectangle rect = TinhToan.ChuyenThanhToaDoHinh(ToaDoVuaDiDen.X, ToaDoVuaDiDen.Y,
                                                               QuanTa.Mau);
                gimg.FillRectangle(ButVe.BDiDen, rect);
                gimg.DrawRectangle(ButVe.PRoiKhoi, rect);
            }
            if (ToaDoVuaRoiKhoi != null)
            {
                Rectangle rect = TinhToan.ChuyenThanhToaDoHinh(ToaDoVuaRoiKhoi.X, ToaDoVuaRoiKhoi.Y,
                                                               QuanTa.Mau);
                gimg.FillRectangle(ButVe.BRoiKhoi, rect);
                gimg.DrawRectangle(ButVe.PRoiKhoi, rect);
            }

            ToaDoBiChieu.ForEach(t =>
                {
                    Rectangle rect = TinhToan.ChuyenThanhToaDoHinh(t.X, t.Y, QuanTa.Mau);
                    gimg.FillRectangle(ButVe.BTanCong, rect);
                    gimg.DrawRectangle(ButVe.PTanCong, rect);
                });


            for (int i = 0; i < 8; i++)
                for (int j = 0; j < 8; j++)
                    if (banCo[i, j] != null)
                    {
                        QuanCo quan = banCo[i, j];
                        Image hinh = TinhToan.LayHinh(quan);
                        Rectangle khung = TinhToan.ChuyenThanhToaDoHinh(quan.ToaDo.X, quan.ToaDo.Y, QuanTa.Mau);
                        gimg.DrawImage(hinh, khung);
                    }

            gpn.DrawImage(img, 0, 0);
            pbQuanTaAn.VeDanhSachQuan(QuanTa.QuanDaAn);
            pbQuanDichAn.VeDanhSachQuan(QuanDich.QuanDaAn);
        }

        private void ResetThoiGian()
        {
            ThoiGianQuanDich = ThoiGianQuanMinh = ThoiGianLuotDi;
        }

        private void pnHinh_MouseClick(object sender, MouseEventArgs e)
        {
            if (DuocPhepDiChuyen && DangChoi)
            {
                ToaDoVuaDiDen = null;
                ToaDoVuaRoiKhoi = null;
                switch (e.Button)
                {
                    case MouseButtons.Left:
                        Vector v = TinhToan.ChuyenThanhToaDoBanCo(e.X, e.Y, QuanTa.Mau);
                        if (ToaDoDangChon == null)
                        {
                            if (v != null && banCo[v.X, v.Y] != null && banCo[v.X, v.Y].Mau == QuanTa.Mau)
                            {
                                QuanCo quan = banCo[v.X, v.Y];

                                ToaDoDangChon = new Vector(v.X, v.Y);
                                quan.TinhToaDoAnhHuong();
                                ToaDoDiChuyen = quan.ToaDoCoTheDiChuyen;
                                ToaDoTanCong = quan.ToaDoCoTheTanCong;
                            }
                            else
                            {
                                XoaDanhSachToaDo();
                            }
                            VeBanCo();
                        }
                        else
                        {
                            if (v != null &&
                                (ToaDoTanCong.Any(t => t.X == v.X && t.Y == v.Y) ||
                                 ToaDoDiChuyen.Any(t => t.X == v.X && t.Y == v.Y)))
                            {
                                DiChuyenViTri(ToaDoDangChon, v);
                                if (banCo[v].CoThePhong)
                                {
                                    var f = new frmPhongTot();
                                    if (f.ShowDialog() == DialogResult.OK)
                                    {
                                        var q = f.Quan;
                                        q.Mau = banCo[v].Mau;
                                        q.ToaDo = v;
                                        q.TrangThai = banCo[v].TrangThai;
                                        q.Ban = banCo;
                                        banCo[v] = q;
                                        if (PhongTot != null)
                                            PhongTot(this, new PhongTotArg(ToaDoDangChon, v, q.GetType().Name));
                                    }
                                }
                                else
                                {
                                    if (DiChuyen != null)
                                        DiChuyen(this, new DiChuyenArgs(ToaDoDangChon, v));
                                }
                            }
                            XoaDanhSachToaDo();
                        }
                        VeBanCo();
                        break;
                    case MouseButtons.Right:
                        XoaDanhSachToaDo();
                        VeBanCo();
                        break;
                }
            }
        }

        private void XoaDanhSachToaDo()
        {
            ToaDoDangChon = null;
            ToaDoDiChuyen.Clear();
            ToaDoTanCong.Clear();
            ToaDoBiChieu.Clear();
        }

        void CapNhatNhatKy(Vector bd, Vector kt)
        {
            if (SoLanDiChuyen % 2 != 0)
            {
                var item = new ListViewItem((SoLanDiChuyen / 2 + 1).ToString());
                item.SubItems.Add(bd + " → " + kt);
                lvNhatKy.Items.Add(item);
            }
            else
            {
                var item = lvNhatKy.Items.OfType<ListViewItem>().Last();
                item.SubItems.Add(bd + " → " + kt);
            }
        }

        public void DiChuyenViTri(Vector bd, Vector kt)
        {
            SoLanDiChuyen++;
            CapNhatNhatKy(bd, kt);
            ToaDoVuaDiDen = bd;
            ToaDoVuaRoiKhoi = kt;
            if (banCo[kt] != null)
            {
                QuanCo quanBiAn = banCo[kt];
                if (quanBiAn.Mau == QuanDich.Mau)
                {
                    QuanTa.QuanDaAn.Add(quanBiAn);
                }
                else
                {
                    QuanDich.QuanDaAn.Add(quanBiAn);
                }
            }
            banCo[bd].DiChuyen(kt);
            banCo[kt] = banCo[bd];
            banCo[bd] = null;

            ToaDoBiChieu = banCo.BiChieu;

            TinhQuyenDiChuyen();
            VeBanCo();
            pbQuanTaAn.VeDanhSachQuan(QuanTa.QuanDaAn);
            pbQuanDichAn.VeDanhSachQuan(QuanDich.QuanDaAn);

            if (cbAmThanh.Checked)
                if (ToaDoBiChieu.Count > 0)
                    PhatAmThanhBiChieu();
                else
                    PhatAmThanhDiChuyen();
        }

        private void PhatAmThanhDiChuyen()
        {
            var simpleSound = new SoundPlayer(Resources.chon);
            simpleSound.Play();
        }

        private void PhatAmThanhBiChieu()
        {
            var simpleSound = new SoundPlayer(Resources.chieu);
            simpleSound.Play();
        }


        private void TinhQuyenDiChuyen()
        {
            if (DuocPhepDiChuyen)
            {
                ThoiGianQuanDich = ThoiGianLuotDi;
                lbStatus.Text = "Đang đợi đối phương đi";
            }
            else
            {
                ThoiGianQuanMinh = ThoiGianLuotDi;
                lbStatus.Text = "Đến lượt bạn";
            }
            DuocPhepDiChuyen = !DuocPhepDiChuyen;
        }

        public void XuLyKetQua(string comment, bool thang = true)
        {
            if (MessageBox.Show(comment) == DialogResult.OK)
            {
                if (thang)
                    QuanTa.SoTranThang++;
                else
                    QuanDich.SoTranThang++;
                CapNhatThongTinVanChoi();
            }

        }

        private void frmGame_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (Thoat != null)
            {
                Thoat(this, EventArgs.Empty);
            }
        }

        private void pnHinh_Paint(object sender, PaintEventArgs e)
        {
            if (DangChoi)
                VeBanCo();
        }

        public void PhongCapChoTot(Vector bd, Vector kt, string quan)
        {
            SoLanDiChuyen++;
            CapNhatNhatKy(bd, kt);
            ToaDoVuaDiDen = bd;
            ToaDoVuaRoiKhoi = kt;
            if (banCo[kt] != null)
            {
                QuanCo quanBiAn = banCo[kt];
                if (quanBiAn.Mau == QuanDich.Mau)
                {
                    QuanTa.QuanDaAn.Add(quanBiAn);
                }
                else
                {
                    QuanDich.QuanDaAn.Add(quanBiAn);
                }
            }

            QuanCo quanCo;
            if (typeof(Tuong).Name.Equals(quan))
                quanCo = new Tuong();
            else if (typeof(Ma).Name.Equals(quan))
                quanCo = new Ma();
            else if (typeof(Xe).Name.Equals(quan))
                quanCo = new Xe();
            else
                quanCo = new Hau();
            quanCo.Ban = banCo;
            quanCo.Mau = banCo[bd].Mau;
            quanCo.ToaDo = kt;
            quanCo.TrangThai = banCo[bd].TrangThai;
            banCo[bd] = null;
            banCo[kt] = quanCo;

            ToaDoBiChieu = banCo.BiChieu;

            TinhQuyenDiChuyen();
            VeBanCo();
            pbQuanTaAn.VeDanhSachQuan(QuanTa.QuanDaAn);
            pbQuanDichAn.VeDanhSachQuan(QuanDich.QuanDaAn);

            if (cbAmThanh.Checked)
                if (ToaDoBiChieu.Count > 0)
                    PhatAmThanhBiChieu();
                else
                    PhatAmThanhDiChuyen();
        }

        private void btnBoCuoc_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Bạn thật sự muốn xin bỏ cuộc ván chơi này?", "", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                if (BoCuoc != null)
                    BoCuoc(this, EventArgs.Empty);
                QuanDich.SoTranThang++;
                CapNhatThongTinVanChoi();
            }
        }

        private void btnThoat_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        public void LuuNhatKyChat(string user, string msg)
        {
            rtxtChat.Write(user + " : ", Color.Black, true);
            rtxtChat.WriteLine(msg, user.Equals(QuanDich.Ten) ? Color.DarkOliveGreen : Color.Sienna);         
            //WriteChat(msg, user.Equals(QuanDich.Ten) ? Color.DarkOliveGreen : Color.Sienna);

        }
        void WriteChat(string msg, Color color)
        {
            int offset = 0;
            rtxtChat.SelectionColor = color;
            while (offset < msg.Length)
            {
                bool r = false;
                foreach (KeyValuePair<string, Image> dic in Emoticions.EmoDic)
                {
                    if (msg.Substring(offset).StartsWith(dic.Key))
                    {
                        PictureBox pic = new PictureBox();
                        var pos = rtxtChat.GetPositionFromCharIndex(rtxtChat.Text.Length);
                        pic.Location = pos;
                        pic.Image = dic.Value;
                        rtxtChat.Controls.Add(pic);
                        offset += dic.Key.Length;
                        r = true;
                        break;
                    }
                }
                if (!r)
                {
                    rtxtChat.AppendText(msg[offset].ToString());
                    offset++;
                }
            }
            rtxtChat.AppendText("\n");
        }
    }
}